package com.chatplus.application.config.pay;

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * 支付配置
 */
@Configuration
@EnableScheduling
@EnableConfigurationProperties
@EnableAspectJAutoProxy()
public class PayConfig {

    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(PayConfig.class);


    public static final String CONFIG_KEY_ROOTS = "chatplus.pay";

    @Bean
    @ConfigurationProperties(CONFIG_KEY_ROOTS)
    public Properties appProperties() {
        return new Properties();
    }

    @Bean
    @ConfigurationProperties(CONFIG_KEY_ROOTS + ".alipay")
    public AliPayProperties aliPayProperties() {
        return new AliPayProperties();
    }

    @Bean
    @ConfigurationProperties(CONFIG_KEY_ROOTS + ".wechat")
    public WechatPayProperties wechatPayProperties() {
        return new WechatPayProperties();
    }

    @Bean
    public WxPayService wxPayContextService(PayConfig.WechatPayProperties wechatConfig) {
        WxPayService wxPayService = new WxPayServiceImpl();
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(StringUtils.trimToNull(wechatConfig.getAppId()));
        payConfig.setMchId(StringUtils.trimToNull(wechatConfig.getMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(wechatConfig.getMchKey()));
        payConfig.setNotifyUrl(StringUtils.trimToNull(wechatConfig.getNotifyUrl()));
        payConfig.setApiV3Key(StringUtils.trimToNull(wechatConfig.getApiV3Key()));
        payConfig.setPrivateKeyPath(StringUtils.trimToNull(wechatConfig.getPrivateKeyPath()));
        payConfig.setPrivateCertPath(StringUtils.trimToNull(wechatConfig.getPrivateCertPath()));
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }

    @Bean
    public Config getOptions(PayConfig.AliPayProperties aliPayConfig) {
        Config config = new Config();
        config.appId = aliPayConfig.getAppId();
        config.protocol = aliPayConfig.getProtocol();
        config.gatewayHost = aliPayConfig.getGatewayHost();
        config.signType = aliPayConfig.getSignType();
        config.alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        config.merchantPrivateKey = aliPayConfig.getAppPrivateKey();
        // 转账等操作需要公钥证书
        config.merchantCertPath = aliPayConfig.getAppCertPath();
        config.alipayCertPath = aliPayConfig.getAlipayCertPath();
        config.alipayRootCertPath = aliPayConfig.getAlipayRootCertPath();
        // 3参数可选
        config.notifyUrl = aliPayConfig.getNotifyUrl();
        config.encryptKey = aliPayConfig.getEncryptKey();
        config.signProvider = aliPayConfig.getSignProvider();
        Factory.setOptions(config);
        return config;
    }

    @Data
    public static class Properties {
        private Long maxPayMoney = Long.MAX_VALUE;
    }

    /**
     * WeChat 配置
     */
    @Data
    public static class WechatPayProperties {
        private boolean enable = false;
        /**
         * 账号适用于那个终端付款如：APP，PC
         */
        private String useFor;
        /**
         * 设置微信公众号或者小程序等的appid
         */
        private String appId;

        /**
         * 微信支付商户号
         */
        private String mchId;

        /**
         * 微信支付商户密钥
         */
        private String mchKey;

        private String apiV3Key;

        /**
         * apiclient_key.p12文件的绝对路径，或者如果放在项目中，请以classpath:开头指定
         */
        private String privateKeyPath;
        /**
         * apiclient_cert.p12文件的绝对路径，或者如果放在项目中，请以classpath:开头指定
         */
        private String privateCertPath;

        /**
         * 业务回调地址
         */
        private String notifyUrl;

        /**
         * 是否进行分账
         */
        private boolean profitSharing;

        /**
         * 分账接收账号
         */
        private String subAccount;

        /**
         * 分账比率
         */
        private String proportion;

        /**
         * 手续费
         */
        private String poundageRate;
    }

    /**
     * Alipay 配置
     */
    @Data
    public static class AliPayProperties {


        private boolean enable = false;
        /**
         * 通信协议，通常填写https
         */
        private String protocol = "https";

        /**
         * 网关域名
         * 线上为：openapi.alipay.com
         * 沙箱为：openapi.alipaydev.com
         */
        private String gatewayHost = "openapi.alipay.com";

        /**
         * AppId
         */
        private String appId;

        /**
         * 签名类型，Alipay Easy SDK只推荐使用RSA2，估此处固定填写RSA2
         */
        private String signType = "RSA2";

        /**
         * 支付宝公钥
         */
        private String alipayPublicKey;

        /**
         * 应用私钥
         */
        private String appPrivateKey;

        /**
         * 应用公钥证书文件路径
         */
        private String appCertPath;

        /**
         * 支付宝公钥证书文件路径
         */
        private String alipayCertPath;

        /**
         * 支付宝根证书文件路径
         */
        private String alipayRootCertPath;

        /**
         * 异步通知回调地址（可选）
         */
        private String notifyUrl;

        /**
         * AES密钥（可选）
         */
        private String encryptKey;

        /**
         * 签名提供方的名称(可选)，例：Aliyun KMS签名，signProvider = "AliyunKMS"
         */
        private String signProvider;

        /**
         * 支付宝授权地址
         */
        private String authorizeUrl = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";

        /**
         * 授权回调
         */
        private String authorizeCallback;

        /**
         * 签约的支付宝账号对应的支付宝唯一用户号，以 2088 开头的 16 位纯数字组成。
         */
        private String pid;

        /**
         * 是否支持沙箱环境(注: 正式环境不用配置,默认即可)
         */
        private boolean supportSandbox = true;
    }
}
